package com.study.hot.jetpack.livedata

import android.util.Log
import androidx.lifecycle.*
import com.study.base.BaseActivity
import com.study.hot.R
import kotlinx.android.synthetic.main.activity_live_data.*
import org.jetbrains.anko.sdk27.coroutines.onClick

/**
 * <pre>
 *     author : fauks
 *     time   : 2020/03/24
 *     desc   : 与RxJava类似，用于观察数据
 *
1.确保界面符合数据状态，当生命周期状态变化时，LiveData通知Observer，可以在observer中更新界面。观察者可以在生命周期状态更改时刷新界面，而不是在每次数据变化时刷新界面。
2.不会发生内存泄漏，observer会在LifecycleOwner状态变为DESTROYED后自动remove。
3.不会因 Activity 停止而导致崩溃，如果LifecycleOwner生命周期处于非活跃状态，则它不会接收任何 LiveData事件。
4.不需要手动解除观察，开发者不需要在onPause或onDestroy方法中解除对LiveData的观察，因为LiveData能感知生命周期状态变化，所以会自动管理所有这些操作。
5.数据始终保持最新状态，数据更新时 若LifecycleOwner为非活跃状态，那么会在变为活跃时接收最新数据。例如，曾经在后台的 Activity 会在返回前台后，observer立即接收最新的数据。
 * </pre>
 */
class LiveDataActivity : BaseActivity() {
    override fun generateLayoutId() = R.layout.activity_live_data

    lateinit var customLiveData: CustomLiveData

    override fun initView() {
        customLiveData = ViewModelProvider(this)[CustomLiveData::class.java]

        //设置liveData的监听，改变后自动更新UI
        customLiveData.liveDataNum.observe(this, Observer {
            liveDataNumTv.text = customLiveData.liveDataNum.value.toString()
        })

        //数据发生改变自动更新UI
        addLiveDataBtn.onClick {
            customLiveData.addNum()
        }

        // 单例的LiveData
        singleInstanceLiveData()

        // LiveData 数据转换/修改
        transformLiveData()

        // 数据切换
        switchLiveData()

        // 观察多个数据源(local、net)：只要任何原始的 LiveData 源对象发生更改，就会触发 MediatorLiveData 对象的观察者
        mediatorLiveData()
    }

    private fun mediatorLiveData() {
        val mediatorLiveData = MediatorLiveData<String>()

        val localLiveData = MutableLiveData<String>()
        val netLiveData = MutableLiveData<String>()

        mediatorLiveData.addSource(localLiveData) {
            Log.i("fauks", "localLiveData change $it")
            mediatorLiveData.value = it
        }
        mediatorLiveData.addSource(netLiveData) {
            Log.i("fauks", "netLiveData change $it")
            mediatorLiveData.value = it
        }

        mediatorLiveData.observe(this, Observer {
            tvStock.text = it
        })

        localLiveData.value = "local list"
        tvStock.postDelayed({
            netLiveData.value = "net list"
        }, 1000)
    }

    private fun switchLiveData() {
        val liveData1 = MutableLiveData<String>()
        val liveData2 = MutableLiveData<String>()
        val switchLiveData = MutableLiveData<Boolean>()

        liveData1.observe(this) {
            tvStock.text = it
        }
        liveData2.observe(this) {
            tvStock.text = it
        }

        Transformations.switchMap(switchLiveData) {
            if (it) liveData1 else liveData2
        }

        var flag = true
        switchLivedataBtn.onClick {
            switchLiveData.value = flag
            flag = !flag
            liveData1.value = "liveData1"
            liveData1.value = "liveData2"
        }
    }

    private fun transformLiveData() {
        val intLiveData = MutableLiveData<Int>()

        val stringLiveData = Transformations.map(intLiveData) {
            "$it ----string"
        }

        stringLiveData.observe(this) {
            Log.i("fauks", "transformLiveData===$it")
        }

        intLiveData.value = 100
    }


    private fun singleInstanceLiveData() {
        StockLiveData.get("xiaomi").observe(this) {
            tvStock.text = "${it.toInt()}"
        }
    }
}